#pragma once
#include <vector>
#include <queue>
#include "HttpRequest.h"
#include "Thread.h"
#include "LockQueue.h"

//
// HttpClient
//
class HttpClient
{
	typedef std::vector<char> Buffer;
	typedef void (*ResponseCallback)(HttpResponse* response);

	struct RequestEntry
	{
		HttpRequest* Request;
		ResponseCallback Callback;
		bool AutoDelete;

		RequestEntry() {}
		RequestEntry(HttpRequest* req, ResponseCallback callback, bool autoDelete)
			: Request(req), Callback(callback), AutoDelete(autoDelete)
		{}
	};
	typedef LockQueue<RequestEntry> RequestQueue;

	static unsigned int __stdcall HttpClientHandle(void *param);

public:
	HttpClient(const std::wstring& URL, int port, const std::wstring& session);
	~HttpClient();

	bool Init();		// init the http client for request & response thread.
	bool Update();		// process the finished requests.
	void Destory();		// destory all of the request, including pending and finished.

	bool PushRequest(HttpRequest* request, ResponseCallback callback = NULL, bool autoDelete = true);

	bool CheckThread() const;

private:
	const std::wstring mURL;
	std::wstring mSession;
	int mPort;

	Thread mThread;
	RequestQueue mPendingQueue;
	RequestQueue mFinishQueue;

private:
	bool Execute(HttpRequest* request);
	bool Execute(const std::wstring& URL, const std::wstring& params, Buffer& outBuff, DWORD& codePage);
	bool Execute(const std::wstring& URL, const std::wstring& params, std::wstring& outString);
};

inline bool HttpClient::CheckThread() const 
{
	return mThread.CheckFinal(); 
}
